//
//  AssetCell.swift
//  GifUsage
//
//  Created by Ting Han on 2020/12/20.
//  Copyright © 2020 Ting Han. All rights reserved.
//

import UIKit
import PhotosUI

class AssetCell: UICollectionViewCell {
    var asset: PHAsset? {
        didSet {
            guard asset != nil else { return }
            updateImage()
        }
    }
    
    var progressHandler: ((Double)-> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    var isPlaying: Bool = false
    
    func play() {
        playerLayer?.player?.play()
        isPlaying = true
    }
    
    func pause() {
        playerLayer?.player?.pause()
        isPlaying = false
    }
    
    private func commonInit() {
        contentView.addSubview(scrollView)
        scrollView.addSubview(imageView)
        scrollView.addSubview(livePhotoView)
        scrollView.addSubview(playerView)
        imageView.frame = contentView.bounds
        livePhotoView.frame = contentView.bounds
        playerView.frame = contentView.bounds
    }
    
    private var isPlayingHint = false
    private var playerLayer: AVPlayerLayer?
    
    lazy var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        imageView.isHidden = true
        return imageView
    }()
    
    lazy var livePhotoView: PHLivePhotoView = {
        let livePhotoView = PHLivePhotoView()
        livePhotoView.contentMode = .scaleAspectFit
        livePhotoView.isHidden = true
        livePhotoView.delegate = self
        return livePhotoView
    }()
    
    lazy var playerView: UIView = {
        let view = UIView()
        view.contentMode = .scaleAspectFit
        view.isHidden = true
        return view
    }()
    
    lazy  var scrollView: UIScrollView = {
        let scrollView = UIScrollView(frame: contentView.bounds)
        scrollView.contentSize = contentView.bounds.size
        return scrollView
    }()
    
   
}
// MARK: 显示
extension AssetCell {
    func updateImage() {
        playerLayer?.player?.pause()
        isPlaying = false
        playerLayer?.removeFromSuperlayer()
        playerLayer = nil
        if asset!.mediaType ==  .image {
            playerView.isHidden = true
           
            if asset!.mediaSubtypes.contains(.photoLive) {
                imageView.isHidden = true
                livePhotoView.isHidden = false
                updateLivePhoto()
            } else {
                imageView.isHidden = false
                livePhotoView.isHidden = true
                updateStaticImage()
            }
        } else { //video & audio
            imageView.isHidden = true
            livePhotoView.isHidden = true
            playerView.isHidden = false
            updateVideo()
        }
    }
    
    var targetSize: CGSize {
        let scale = UIScreen.main.scale
        return CGSize(width: imageView.bounds.width * scale,
                      height: imageView.bounds.height * scale)
    }
    
    func updateLivePhoto() {
        let options = PHLivePhotoRequestOptions()
        options.deliveryMode = .highQualityFormat
        options.isNetworkAccessAllowed = true
        options.progressHandler = { progress, _, _, _ in
            self.progressHandler?(progress)
        }
        
        PHImageManager.default().requestLivePhoto(for: asset!, targetSize: targetSize, contentMode: .aspectFit, options: options) { (livePhoto, info) in
            guard let livePhoto = livePhoto else { return }
            DispatchQueue.main.async {
                self.livePhotoView.livePhoto = livePhoto
                if !self.isPlayingHint {
                    self.isPlayingHint = true
                    self.livePhotoView.startPlayback(with: .hint)
                }
            }
            
        }
    }
    
    func updateStaticImage() {
        let resourceGIF = asset!.gifResource
        if resourceGIF == nil { // image
            let options = PHImageRequestOptions()
            options.deliveryMode = .highQualityFormat
            options.isNetworkAccessAllowed = true
            options.progressHandler = { progress, _, _, _ in
                self.progressHandler?(progress)
            }
            
            PHImageManager.default().requestImage(for: asset!, targetSize: targetSize, contentMode: .aspectFit, options: options, resultHandler: { image, _ in
                guard let image = image else { return }

                self.imageView.image = image
            })
            
        } else { // gif
            let resourceOption = PHAssetResourceRequestOptions()
            resourceOption.isNetworkAccessAllowed = true
            resourceOption.progressHandler = { progress in
                self.progressHandler?(progress)
            }
            
            var gifData = Data()
            PHAssetResourceManager.default().requestData(for: resourceGIF!, options: resourceOption) { (data) in
                gifData.append(data)
                
            } completionHandler: { (error) in
                DispatchQueue.main.async {
                    self.imageView.animate(withGIFData: gifData)
                }
            }
        }
    }
    
    func updateVideo() {
        let options = PHVideoRequestOptions()
        options.isNetworkAccessAllowed = true
        options.deliveryMode = .automatic
        options.progressHandler = { progress, _, _, _ in
            self.progressHandler?(progress)
        }
        
        PHImageManager.default().requestPlayerItem(forVideo: asset!, options: options, resultHandler: { playerItem, info in
            DispatchQueue.main.async {
                guard self.playerLayer == nil else { return }
                let player = AVPlayer(playerItem: playerItem)
                let playerLayer = AVPlayerLayer(player: player)
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
                playerLayer.frame = self.playerView.layer.bounds
                self.playerView.layer.addSublayer(playerLayer)
                self.playerLayer = playerLayer
            }
        })
    }
    
    
    func copyDisplayView() -> UIView {
        if asset?.mediaType != .image {
            return playerView
        } else {
            if asset?.mediaSubtypes.contains(.photoLive) == true {
                return livePhotoView
            } else {
                return imageView
            }
        }
    }
}

// MARK: PHLivePhotoViewDelegate
extension AssetCell: PHLivePhotoViewDelegate {
    func livePhotoView(_ livePhotoView: PHLivePhotoView, willBeginPlaybackWith playbackStyle: PHLivePhotoViewPlaybackStyle) {
        isPlayingHint = (playbackStyle == .hint)
    }

    func livePhotoView(_ livePhotoView: PHLivePhotoView, didEndPlaybackWith playbackStyle: PHLivePhotoViewPlaybackStyle) {
        isPlayingHint = (playbackStyle == .hint)
    }
}


